package com.jeedcp.shiro.jwt;

import com.jeedcp.core.common.Status;
import com.jeedcp.core.exception.BusinessException;
import com.jeedcp.shiro.sys.entity.User;
import com.jeedcp.shiro.sys.service.IMenuService;
import com.jeedcp.shiro.sys.service.IUserService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Set;

/**
 * @project: demo
 * @description: JWT 认证
 * @author: caochaofeng
 * @create: 2019-08-14 16:08
 */
@Component
public class JwtRealm extends AuthorizingRealm {

    @Autowired
    private IUserService userService;

    @Autowired
    private IMenuService menuService;

    @Override
    public Class<?> getAuthenticationTokenClass() {
        return JwtToken.class;
    }
    /**
     * 认证(登录时调用)
     *
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String token = (String) authenticationToken.getCredentials();
        String username = JwtUtil.getUserNameByToken(token);
        if(StringUtils.isBlank(username)){
            throw new IncorrectCredentialsException(Status.FAIL_INVALID_TOKEN.message());
        }else{
            // 获取认证方式
            User user = userService.getUserByUsername(username);
            // 登录失败则抛出相关异常
            if (user == null){
                throw new BusinessException(Status.ACCOUNT_NOT_EXIST.code());
            }
            if (!JwtUtil.verify(token,username,user.getPassword())){
                throw new BusinessException(Status.ACCOUNT_PASSWORD_ERROR.code());
            }
            return new SimpleAuthenticationInfo(user, token, this.getName());
        }
    }


    /**
     * 授权(验证权限时调用)
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        User user = (User)  principalCollection.getPrimaryPrincipal();
        // 整理所有权限许可列表
        Set<String> permissions =  menuService.getUserPermissionsList(user);
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        // 将权限许可授权给用户
        info.setStringPermissions(permissions);
        return info;
    }
}
